﻿/*
* BaseCorps.cpp
*
* 军团基类
*
* create date: 2014.4.11
* create by: leo
*
*/

#include <float.h>
#include "BaseCorps.h"

#include "EmptyCorps.h"
#include "../scenes/BattleScene.h"
#include "CorpsFormation.h"
#include "../heros/BaseHero.h"

USING_NS_CC;

void CBaseCorps::addHero(CBaseHero& hero)
{
	if (!mHeros.containsObject(&hero))
	{
		mHeros.addObject(&hero);
	}
	hero.setCorps(*this);
	hero.addStateListener(*this);
}

void CBaseCorps::removeHero(CBaseHero& hero)
{
	mHeros.removeObject(&hero);
	hero.removeStateListener(*this);
}

void CBaseCorps::removeAllHero()
{
	mHeros.removeAllObjects();
}

CBaseCorps::CBaseCorps()
: BattleScene(NULL),
  mOnDefeatObj(this),
  mOnDefeatCallback(callfuncO_selector(CBaseCorps::doNothing)),
  mFormation(new CCorpsFormation())
{}

CBaseCorps::~CBaseCorps()
{}

void CBaseCorps::preloadRes()
{
	CCObject* obj = NULL;
	CCARRAY_FOREACH(&mHeros, obj)
	{
		CBaseHero* hero = (CBaseHero*)obj;
		hero->preloadRes();
	}
}

void CBaseCorps::setOnDefeatListener(CCObject* callbackObj, SEL_CallFuncO onDefeatCallback)
{
	mOnDefeatObj = callbackObj;
	mOnDefeatCallback = onDefeatCallback;
}

void CBaseCorps::startBattle(CBattleScene& battleScene)
{
	BattleScene = &battleScene;
	CBaseCorps* enemy = battleScene.getEnemyCorps(*this);

	CCObject* obj = NULL;
	CCARRAY_FOREACH(&mHeros, obj)
	{
		CBaseHero* hero = (CBaseHero*)obj;
		hero->setEnemyCorps(*enemy);
		battleScene.addChild(hero);
		battleScene.addSortNode(hero);
		hero->scheduleUpdate();
	}

	mFormation->formation(mHeros);
}

CBaseHero* CBaseCorps::getNearestHero(CBaseHero& nearBy)
{
	if (mHeros.count() > 0)
	{
		float dis = FLT_MAX;
		CBaseHero* nearestHero = NULL;
		CCObject* obj = NULL;
		CCARRAY_FOREACH(&mHeros, obj)
		{
			CBaseHero* hero = (CBaseHero*)obj;
			if (hero->isAlive())
			{
				float tDis = ccpDistance(hero->getPosition(), nearBy.getPosition());
				if (tDis < dis)
				{
					nearestHero = hero;
					dis = tDis;
				}
			}
		}
		return nearestHero;
	}

	return NULL;
}

CBaseHero* CBaseCorps::getRandomHero()
{
	if (mHeros.count() > 0)
	{
		return (CBaseHero*)(mHeros.objectAtIndex((int)(mHeros.count() * CCRANDOM_0_1())));
	}

	return NULL;
}

void CBaseCorps::setCorpsFormation(CCorpsFormation& formation)
{
	mFormation = &formation;
}

void CBaseCorps::winGame()
{
    CCObject* obj = NULL;
	CCARRAY_FOREACH(&mHeros, obj)
	{
		CBaseHero* hero = (CBaseHero*)obj;
		if (hero->isAlive())
		{
			hero->victory();
		}
	}

}

void CBaseCorps::doNothing(cocos2d::CCObject* obj)
{}

void CBaseCorps::onDied(CBaseHero& hero)
{
	CCObject* obj = NULL;
	CCARRAY_FOREACH(&mHeros, obj)
	{
		CBaseHero* hero = (CBaseHero*)obj;
		if (hero->isAlive())
		{
			return;
		}
	}

	(mOnDefeatObj->*mOnDefeatCallback)(this);
}

void CBaseCorps::onPositionChange(CBaseHero& hero)
{}

CEmptyCorps CBaseCorps::EmptyCorps;
